package test.panel4;

import test.CPU.CPUController;
import test.CPU.CPUObserver;
import test.panel3.ProcessTableInPanel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class Control implements CPUObserver {
    public static Control instance = new Control();
    public static Map<Integer, Process> running_process = new HashMap<>();
    public static Map<Integer, Process> suspend_process = new HashMap<>();
    public static Map<Integer, Process> processes = new HashMap<>();
    public static Map<Integer, ProcessPanel> panels = new HashMap<>();

    public static String scheduler = "先来先服务(FCFS)";

    private Control() {
        CPUController.addObserver(this);
    }

    static public void suspend(Process process) {
        process.isRunning = false;
        process.state = "挂起";
        running_process.remove(process.pid);
        suspend_process.put(process.pid, process);
        Panel4.removeFromTop(panels.get(process.pid));
        panels.remove(process.pid);
        ProcessPanel panel = new ProcessPanel(process);
        panels.put(process.pid, panel);
        Panel4.addToBottom(panel);
    }

    static public void active(Process process) {
        process.isRunning = true;
        process.state = "阻塞";
        suspend_process.remove(process.pid);
        running_process.put(process.pid, process);
        Panel4.removeFromBottom(panels.get(process.pid));
        panels.remove(process.pid);
        ProcessPanel panel = new ProcessPanel(process);
        panels.put(process.pid, panel);
        Panel4.addToTop(panel);
    }

    static public void delete(Process process) {
        processes.remove(process.pid);
        if (process.isRunning) {
            running_process.remove(process.pid);
            Panel4.removeFromTop(panels.get(process.pid));
        } else {
            suspend_process.remove(process.pid);
            Panel4.removeFromBottom(panels.get(process.pid));
        }
        panels.remove(process.pid);

    }

    static public void addProcess(String name, boolean isRunning) {
        Process process = new Process(name + Process.nextPid, isRunning);
        ProcessPanel processPanel = new ProcessPanel(process);
        panels.put(process.pid, processPanel);
        if (isRunning) {
            running_process.put(process.pid, process);
            Panel4.addToTop(processPanel);
        } else {
            suspend_process.put(process.pid, process);
            Panel4.addToBottom(processPanel);
        }
        ProcessTableInPanel.getInstance().addData(process);
    }

    //详细设置按钮的详细逻辑
    public static void setting(Process process) {
        JDialog dialog = new JDialog((Frame) null, "进程设置", true);
        dialog.setLayout(new BorderLayout());

        JTabbedPane tabbedPane = new JTabbedPane();
        //第一个标签页
        JPanel basicPanel = new JPanel(new GridLayout(2, 2));
        //名字标签
        JTextField nameField = new JTextField(process.name, 20);
        JPanel namePanel = new JPanel();
        namePanel.add(new JLabel("进程名称:"));
        namePanel.add(nameField);
        //内存标签
        JTextField memoryField = new JTextField(String.valueOf(process.memory), 20);
        JPanel memoryPanel = new JPanel();
        memoryPanel.add(new JLabel("所需内存"));
        memoryPanel.add(memoryField);
        //设置周期
        JTextField periodField = new JTextField(String.valueOf(process.period), 20);
        JPanel periodPanel = new JPanel();
        periodPanel.add(new JLabel("运行周期"));
        periodPanel.add(periodField);
        //设置所需时间
        JTextField needTimeField = new JTextField(String.valueOf(process.needTime), 20);
        JPanel needTimePanel = new JPanel();
        needTimePanel.add(new JLabel("所需时间"));
        needTimePanel.add(needTimeField);
        basicPanel.add(namePanel);
        basicPanel.add(memoryPanel);
        basicPanel.add(periodPanel);
        basicPanel.add(needTimePanel);

        JPanel needsPanel = new JPanel(new BorderLayout());
        JPanel addResourcePanel = new JPanel();
        JTextField resourceIdField = new JTextField(5);
        JTextField resourceAmountField = new JTextField(5);
        JButton addResourceButton = new JButton("添加资源");
        JButton deleteResourceButton = new JButton("删除资源");

        addResourcePanel.add(new JLabel("资源ID:"));
        addResourcePanel.add(resourceIdField);
        addResourcePanel.add(new JLabel("数量:"));
        addResourcePanel.add(resourceAmountField);
        addResourcePanel.add(addResourceButton);
        addResourcePanel.add(deleteResourceButton);

        needsPanel.add(addResourcePanel, BorderLayout.NORTH);

        JTextArea needsTextArea = new JTextArea(10, 30);
        needsPanel.add(new JScrollPane(needsTextArea), BorderLayout.CENTER);

        updateNeedsTextArea(process, needsTextArea);

        addResourceButton.addActionListener(e -> {
            try {
                int resourceId = Integer.parseInt(resourceIdField.getText());
                int resourceAmount = Integer.parseInt(resourceAmountField.getText());
                process.Needs.put(resourceId, resourceAmount);
                updateNeedsTextArea(process, needsTextArea);
                resourceIdField.setText("");
                resourceAmountField.setText("");
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(dialog, "输入无效，请输入有效的整数", "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        deleteResourceButton.addActionListener(e -> {
            try {
                int resourceId = Integer.parseInt(resourceIdField.getText());
                if (process.Needs.remove(resourceId) != null) {
                    JOptionPane.showMessageDialog(dialog, "资源已删除", "信息", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    JOptionPane.showMessageDialog(dialog, "资源ID不存在", "错误", JOptionPane.ERROR_MESSAGE);
                }
                updateNeedsTextArea(process, needsTextArea);
                resourceIdField.setText("");
                resourceAmountField.setText("");
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(dialog, "输入无效，请输入有效的整数", "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        tabbedPane.add("基本信息", basicPanel);
        tabbedPane.add("所需资源", needsPanel);

        dialog.add(tabbedPane, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();
        JButton okButton = new JButton("确定");
        okButton.addActionListener(e -> {
            process.name = nameField.getText();//修改进程名
            try {
                //修改进程所需内存
                int needsMemory = Integer.parseInt(memoryField.getText());
                process.memory = needsMemory;
                ProcessTableInPanel.getInstance().updateDiskSize(process.pid, needsMemory);
                //修改周期
                int period = Integer.parseInt(periodField.getText());
                process.period = period;
                //修改所需时间
                int needsTime = Integer.parseInt(needTimeField.getText());
                process.needTime = needsTime;
                dialog.dispose();
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(dialog, "输入无效，请输入有效的整数", "错误", JOptionPane.ERROR_MESSAGE);
            }
        });
        buttonPanel.add(okButton);

        dialog.add(buttonPanel, BorderLayout.SOUTH);

        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        panels.get(process.pid).setName(process.name);
    }

    private static void updateNeedsTextArea(Process process, JTextArea needsTextArea) {
        needsTextArea.setText("");
        process.Needs.forEach((key, value) -> needsTextArea.append("资源ID: " + key + ", 数量: " + value + "\n"));
    }

    public static void blockAllProcesses() {
        for (Map.Entry<Integer, Process> entry : running_process.entrySet()) {
            if (Objects.equals(entry.getValue().state, "完成") || Objects.equals(entry.getValue().state, "资源不足"))
                continue;
            entry.getValue().state = "阻塞";
        }
    }

    @Override
    public void CPUUpdate(int clock) {
        Panel4.updateLeftList();
        for (Map.Entry<Integer, Process> entry : running_process.entrySet()) {
            if (clock % entry.getValue().period == 0) {
                if (!Objects.equals(entry.getValue().state, "完成")) System.out.println(entry.getValue().name + "错过");
                else entry.getValue().state = "阻塞";
                entry.getValue().workedTime = 0;
            }
        }
    }
}
